//! 核心抽象层Mock测试
//! 
//! 为配置中心模块的核心trait接口提供Mock实现和基本测试

use crate::core::*;
use std::collections::HashMap;
use std::time::SystemTime;
use async_trait::async_trait;
use serde_json::json;

/// 简单的错误类型用于测试
#[derive(Debug)]
pub enum TestError {
    NotFound(String),
}

impl std::fmt::Display for TestError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            TestError::NotFound(msg) => write!(f, "未找到: {}", msg),
        }
    }
}

impl std::error::Error for TestError {}

#[cfg(test)]
mod simplified_tests {
    use super::*;
    use crate::config::RustCloudConfig;
    
    /// 简单的Mock数据库存储提供者
    pub struct SimpleMockStorage {
        data: HashMap<String, ConfigurationData>,
    }
    
    impl SimpleMockStorage {
        pub fn new() -> Self {
            Self {
                data: HashMap::new(),
            }
        }
        
        pub fn add_config(&mut self, app: &str, profile: &str, label: &str, config: RustCloudConfig) {
            let env = ConfigEnvironment {
                application: app.to_string(),
                profile: profile.to_string(),
                label: label.to_string(),
            };
            
            let data = ConfigurationData {
                environment: env,
                config,
                version: "v1.0.0".to_string(),
                last_modified: SystemTime::now(),
                source: "test".to_string(),
                properties: HashMap::new(),
            };
            
            let key = format!("{}:{}:{}", app, profile, label);
            self.data.insert(key, data);
        }
    }
    
    #[async_trait]
    impl ConfigurationStorage for SimpleMockStorage {
        async fn load(&self, environment: &ConfigEnvironment) -> ConfigurationResult<ConfigurationData> {
            let key = format!("{}:{}:{}", environment.application, environment.profile, environment.label);
            if let Some(data) = self.data.get(&key) {
                Ok(data.clone())
            } else {
                Err(Box::new(TestError::NotFound(format!("配置不存在: {}", key))))
            }
        }
        
        async fn save(&self, _data: &ConfigurationData, _user: &str) -> ConfigurationResult<String> {
            Ok("v1.0.0".to_string())
        }
        
        async fn delete(&self, _environment: &ConfigEnvironment, _user: &str) -> ConfigurationResult<()> {
            Ok(())
        }
        
        async fn get_history(&self, _environment: &ConfigEnvironment) -> ConfigurationResult<Vec<ConfigurationChange>> {
            Ok(Vec::new())
        }
        
        async fn rollback(&self, _environment: &ConfigEnvironment, _version: &str, _user: &str) -> ConfigurationResult<()> {
            Ok(())
        }
        
        async fn initialize(&self) -> ConfigurationResult<()> {
            Ok(())
        }
        

    }
    

    
    #[tokio::test]
    async fn test_simple_mock_storage() {
        let mut storage = SimpleMockStorage::new();
        
        // 添加测试数据
        storage.add_config("test-app", "dev", "master", RustCloudConfig::default());
        
        // 测试加载配置
        let env = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };
        
        let result = storage.load(&env).await;
        assert!(result.is_ok());
        
        let data = result.unwrap();
        assert_eq!(data.environment.application, "test-app");
        assert_eq!(data.version, "v1.0.0");
        
        // 测试不存在的配置
        let nonexistent_env = ConfigEnvironment {
            application: "nonexistent".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };
        
        let result = storage.load(&nonexistent_env).await;
        assert!(result.is_err());
    }
    
    #[tokio::test]
    async fn test_simple_mock_storage_other_methods() {
        let storage = SimpleMockStorage::new();
        
        let env = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };
        
        let data = ConfigurationData {
            environment: env.clone(),
            config: RustCloudConfig::default(),
            version: "v1.0.0".to_string(),
            last_modified: SystemTime::now(),
            source: "test".to_string(),
            properties: HashMap::new(),
        };
        
        // 测试保存
        let version = storage.save(&data, "test-user").await.unwrap();
        assert_eq!(version, "v1.0.0");
        
        // 测试删除
        assert!(storage.delete(&env, "test-user").await.is_ok());
        
        // 测试历史
        let history = storage.get_history(&env).await.unwrap();
        assert!(history.is_empty());
        
        // 测试回滚
        assert!(storage.rollback(&env, "v1.0.0", "test-user").await.is_ok());
        
        // 测试初始化
        assert!(storage.initialize().await.is_ok());
        
        // 测试初始化
        assert!(storage.initialize().await.is_ok());
    }
    

    
    #[tokio::test]
    async fn test_configuration_environment() {
        let env = ConfigEnvironment {
            application: "user-service".to_string(),
            profile: "production".to_string(),
            label: "v2.1.0".to_string(),
        };
        
        assert_eq!(env.application, "user-service");
        assert_eq!(env.profile, "production");
        assert_eq!(env.label, "v2.1.0");
        
        // 测试克隆
        let cloned_env = env.clone();
        assert_eq!(cloned_env.application, env.application);
        assert_eq!(cloned_env.profile, env.profile);
        assert_eq!(cloned_env.label, env.label);
    }
    
    #[tokio::test]
    async fn test_configuration_data_structure() {
        let env = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };
        
        let mut properties = HashMap::new();
        properties.insert("author".to_string(), json!("test-user"));
        properties.insert("purpose".to_string(), json!("testing"));
        
        let data = ConfigurationData {
            environment: env.clone(),
            config: RustCloudConfig::default(),
            version: "v1.2.3".to_string(),
            last_modified: SystemTime::now(),
            source: "admin".to_string(),
            properties: properties.clone(),
        };
        
        assert_eq!(data.environment.application, "test-app");
        assert_eq!(data.version, "v1.2.3");
        assert_eq!(data.source, "admin");
        assert_eq!(data.properties.len(), 2);
        assert_eq!(data.properties.get("author"), Some(&json!("test-user")));
    }
}